import pika
import uuid
import json

class FibonacciRpcClient(object):
#创建连接
    def __init__(self):
        credentials = pika.PlainCredentials('chenjing', '253455')
        self.connection = pika.BlockingConnection(
            pika.ConnectionParameters(host='192.168.31.80', port=5672, virtual_host='/', credentials=credentials))

        self.channel = self.connection.channel()
#创建回调队列
        result = self.channel.queue_declare(queue='', exclusive=True)
        self.callback_queue = result.method.queue

#这个是消息发送方，当要执行回调的时候，它又是接受方
#使用callback_queue实现消息接收，就是回调。注意：这里的回调不需要对消息进行确认，反复确认就成了死循环
        self.channel.basic_consume(
            queue=self.callback_queue,
            on_message_callback=self.on_response,
            auto_ack=True)
#定义回调的响应函数
#判断当前回调ID和响应的ID是否相同，以防诺发起上百个请求，发送端总得知道回来的对应的哪一个发送的
    def on_response(self, ch, method, props, body):#correlation_id用于将RPC响应与请求相关联
        if self.corr_id == props.correlation_id:
            self.response = body

    def call(self, n):
        #设置响应和回调通道的ID
        self.response = None
        self.corr_id = str(uuid.uuid4())
        #properties中reolay_to：表示回调要调用哪个函数
        #correlation_id:表示回调返回的请求ID是哪个
        #body:要交给接收端的参数
        self.channel.basic_publish(
            exchange='topic_logs',
            routing_key='kk.cj2.oo',
            properties=pika.BasicProperties(
                reply_to=self.callback_queue,#reply_to:通常用于命名回调队列
                correlation_id=self.corr_id,
            ),
            body=str(n))
        #监听回调
        while self.response is None:
            self.connection.process_data_events()
        return eval(self.response)#返回的结果是整数，这里进行强制转换


fibonacci_rpc = FibonacciRpcClient()

print(" 发送数据")
response = fibonacci_rpc.call(1)
print(response)
# with open('test_data','w') as f:
#   for each in response:
#     json_str = json.dumps(each)
#     f.write(json_str+'\n')

